package oop.core.item;
/**
 * 
 * This is the Inventory that Entity has
 * It holds items 
 * @author Hoang Le
 *
 */

import java.util.ArrayList;

public class Inventory 
{
	private static final int INVENTORY_SIZE = 32;
	private TakeableItem[] itemList;
	private int[] itemMultiplicity;
	private int currentNumItem;
	private boolean full;
	
	public Inventory()
	{
		itemList = new TakeableItem[INVENTORY_SIZE];
		itemMultiplicity = new int[INVENTORY_SIZE];
		for (int i = 0; i < itemMultiplicity.length; i++)
		{
			itemMultiplicity[i] = 0; 
		}
		currentNumItem = 0;
		full = false;
	}
	
	/**
	 * This constructor would only be used via loading
	 * or when parse from a File, otherwise Avatar should use 
	 * empty constructor when game starts.	
	 */
	public Inventory(TakeableItem[] itemList, int[] itemMultiplicity) throws Exception
	{
		setItemList(itemList);
		setItemMultiplicity(itemMultiplicity);
		
	}
	
	public int getCurrentNumItem()
	{
		return currentNumItem;
	}
	
	public void setItemMultiplicity(int[] itemMultiplicty) throws Exception
	{
		if(itemList.length != INVENTORY_SIZE)
		{
			throw new Exception("Invalid itemMultiplicity size");
		}
		else
		{
			this.itemMultiplicity = itemMultiplicty;
		}
	}
	

	public void setItemList(TakeableItem[] itemList) throws Exception
	{
		if(itemList.length != INVENTORY_SIZE)
		{
			throw new Exception("Invalid itemList Size");
		}
		else
		{
			this.itemList = itemList;
			updateCurrentNumItem();
		}
		
	}
	/**
	 * Update the current number of items in this inventory
	 */
	
	public void updateCurrentNumItem()
	{
		int tempCount = 0;
		for(int i = 0; i < INVENTORY_SIZE; i++)
		{
			if(itemList[i] != null)
			{
				tempCount++;
			}
		}
		currentNumItem = tempCount;
		if (currentNumItem == INVENTORY_SIZE)
		{
			full = true;
		}
	}
	
	/**
	 * Add item into inventory
	 * @param item
	 * @return
	 */
	public boolean addItem(TakeableItem item)
	{
		//currentNumitem should never be greater than
		//INVENTORY_SIZE, but just do it down here to
		//cover all cases
		if(currentNumItem >= INVENTORY_SIZE)
		{
			if(!hasItem(item))
			{
				return false; 
			}
			else
			{
				for(int i = 0; i < INVENTORY_SIZE; i++)
				{
					if(itemList[i] != null)
					{
						if(itemList[i].equals(item))
						{
							itemMultiplicity[i] = itemMultiplicity[i] + 1;
							break;
						}
					}
				}
				return true;
			
			}
			
		}
		
		else
		{
			for(int i = 0; i < INVENTORY_SIZE; i++)
			{
				if(hasItem(item))
				{
					itemMultiplicity[i] = itemMultiplicity[i] + 1;
					break;
				}
				if(itemList[i] == null)
				{
					itemList[i] = item;
					itemMultiplicity[i] = itemMultiplicity[i] + 1;
					updateCurrentNumItem();
					break;
				}
			}
			return true;
			
		}

		
	}
	
	/**
	 * Remove item from inventory
	 * @param item
	 * @return
	 */
	public TakeableItem removeItem(TakeableItem item)
	{
		if(item == null)
		{
			return null;
		}
		TakeableItem ret = null;
		if(hasItem(item))
		{
			for(int i = 0; i < INVENTORY_SIZE; i++)
			{
				if(itemList[i] != null)
				{
					if(itemList[i].equals(item))
					{
						if(itemMultiplicity[i] > 1)
						{
							ret = itemList[i];
							itemMultiplicity[i] = itemMultiplicity[i] - 1;
							break;
						}
						else
						{
							ret = itemList[i];
							itemList[i] = null;
							itemMultiplicity[i] = 0;
							updateCurrentNumItem();
							break;
						}
					}
				}
					
			}
			return ret;
		}
		return ret;
		
	}
	
	/**
	 * remove item using an index (for the view purpose)
	 * @param index
	 * @return
	 */
	
	public TakeableItem removeItem(int index)
	{
		return removeItem(itemList[index]);
	}
	
	
	/**
	 * check to see if this item exists in the inventory
	 * @param item
	 * @return
	 */
	public boolean hasItem(TakeableItem item)
	{
		for(int i = 0; i < INVENTORY_SIZE; i++)
		{
			if(itemList[i] != null)
			{
				if(itemList[i].equals(item))
				{
					return true;
				}
			}
		}
		return false;
	}
	
	/**
	 * check if the item exists in the inventory passing
	 * in the string name of the item
	 * @param itemName
	 * @return
	 */
	
	public boolean hasItem(String itemName)
	{
		for(int i = 0; i < INVENTORY_SIZE; i++)
		{
			if(itemList[i] != null)
			{
				if(itemList[i].getName().equals(itemName))
				{
					return true;
				}
			}
		}
		return false;
	}
	/**
	 * check to see if inventory is full
	 * @return
	 */
	
	public boolean isFull()
	{
		return full;
	}
	/**
	 * check to see if an item can be added to inventory
	 * @param item
	 * @return
	 */
	
	public boolean canAdd(TakeableItem item)
	{
		return hasItem(item) || !isFull();
	}

	public TakeableItem getItem(int index)
	{
		return itemList[index];
	}
	
	/**
	 * get a random item from inventory
	 * @return
	 */
	
	public TakeableItem getRandomItem()
	{
		while(true)
		{
			int rand = (int) (Math.random() * 10);
			if(itemList[rand] != null)
			{
				TakeableItem item = removeItem(rand);
				return item;
			}
			
		}
	}
}